package cn.stu.cms.controller;


import cn.stu.cms.dto.FileDto;
import cn.stu.cms.pojo.File;
import cn.stu.cms.service.FileService;
import cn.stu.cms.util.R;
import cn.stu.cms.util.UserHolder;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.minio.errors.ErrorResponseException;
import io.minio.errors.InsufficientDataException;
import io.minio.errors.InvalidResponseException;
import io.minio.errors.XmlParserException;
import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
import lombok.AllArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.rmi.ServerException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * 文件控制器
 *
 * @author gh
 * @date 2023/09/14
 */
@RestController
@RequestMapping("/files")
@AllArgsConstructor
public class FileController {

    private FileService fileService;


    /**
     * 列表文件
     *
     * @param pageNumber 页码
     * @param pageSize   页面大小
     * @param dto        DTO
     * @return {@link R}
     */
    @GetMapping
    public R<Page<File>> listFile(@RequestParam(defaultValue = "1") int pageNumber, @RequestParam(defaultValue = "10") int pageSize, FileDto dto) {
        if (!Boolean.TRUE.equals(dto.getShared())) {
            dto.setUserId(UserHolder.getUser().getUserId());
        }
        return fileService.listByEntity(pageNumber, pageSize, dto);
    }

    /**
     * 创建文件
     *
     * @param multipartFile 多部分文件
     * @param file          文件
     * @return {@link R}
     * @throws IOException               IOEXCEPTION
     * @throws ServerException           服务器异常
     * @throws InsufficientDataException 数据不足异常
     * @throws NoSuchAlgorithmException  没有这样算法异常
     * @throws InternalException         内部异常
     * @throws InvalidResponseException  无效响应异常
     * @throws XmlParserException        XML解析器异常
     * @throws InvalidKeyException       无效键异常
     * @throws ErrorResponseException    错误响应异常
     * @throws ServerException           服务器异常
     * @throws InternalException         内部异常
     */
    @PostMapping
    public R<File> createFile(@RequestParam(required = false) MultipartFile multipartFile, @Validated({File.CreateFile.class, File.CreateFolder.class}) File file)
            throws IOException, ServerException, InsufficientDataException, NoSuchAlgorithmException, InternalException,
            InvalidResponseException, XmlParserException, InvalidKeyException, ErrorResponseException, io.minio.errors.ServerException, io.minio.errors.InternalException {
        return fileService.create(multipartFile, file);
    }

    /**
     * 下载文件文件
     *
     * @param id       ID
     * @param response 响应
     * @throws IOException               IOEXCEPTION
     * @throws ServerException           服务器异常
     * @throws InsufficientDataException 数据不足异常
     * @throws NoSuchAlgorithmException  没有这样算法异常
     * @throws InternalException         内部异常
     * @throws InvalidResponseException  无效响应异常
     * @throws XmlParserException        XML解析器异常
     * @throws InvalidKeyException       无效键异常
     * @throws ErrorResponseException    错误响应异常
     * @throws ServerException           服务器异常
     * @throws InternalException         内部异常
     */
    @GetMapping("/{id}")
    public void downloadFile(@PathVariable Long id, HttpServletResponse response) throws IOException, ServerException, InsufficientDataException,
            NoSuchAlgorithmException, InternalException, InvalidResponseException, XmlParserException, InvalidKeyException, ErrorResponseException, io.minio.errors.ServerException, io.minio.errors.InternalException {
        fileService.getById(id, response);
    }

    /**
     * 更新文件
     *
     * @param file 文件
     * @return {@link R}
     */
    @PutMapping
    public R<File> updateFile(@RequestBody @Validated({File.Update.class}) File file) {
        return fileService.update(file);
    }

    /**
     * 删除文件
     *
     * @param id ID
     * @return {@link R}
     * @throws IOException               IOEXCEPTION
     * @throws InvalidResponseException  无效响应异常
     * @throws InvalidKeyException       无效键异常
     * @throws NoSuchAlgorithmException  没有这样算法异常
     * @throws ServerException           服务器异常
     * @throws ErrorResponseException    错误响应异常
     * @throws XmlParserException        XML解析器异常
     * @throws InsufficientDataException 数据不足异常
     * @throws InternalException         内部异常
     */
    @DeleteMapping("/{id}")
    public R<String> deleteFile(@PathVariable Long id) throws IOException, InvalidResponseException, InvalidKeyException,
            NoSuchAlgorithmException, ServerException, ErrorResponseException, XmlParserException, InsufficientDataException, InternalException {
        return fileService.deleteById(id);
    }
}